/**
 *@file: FileServices.java
 *
 * PURPOSE:
 * Utility file services to delete directory+contents and get file listing from directory name, etc
 *
 * @author Kenneth J Kline
 *
 * REVISION HISTORY ABSTRACT
 *
 * PROGRAMMER:  Kenneth J Kline       ORG: MSE
 * 10JUN2011 ORIGINAL INSTANTIATION
 *
 * Copyright 2011 Mission Solutions LLC.  All rights reserved.
 *
 * END ABSTRACT
 */
package com.mse.utilities;

import java.io.BufferedReader;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
 * DESCRIPTION:
 * <p>
 * Utility file services to delete directory+contents and get file listing from directory name, etc
 */
public class FileServices {
    
    /**
     * DESCRIPTION:
     * <p>
     * gets and returns a list of entries in a directory which contain the input wildcard
     * 
     * @param dirName name of directory to get listing of
     * @param wild wildcard string
     * @return list of filenames that exist in the directory specified
     */
    public static List<String> getDirectoryList(String dirName, String wildcard) {
        final String wild = wildcard;
        List<String>fileNames = new ArrayList<String>();
        File dir = new File(dirName);
        String[] children = dir.list(new FilenameFilter() {
            @Override
            public boolean accept(File file, String name) {
                return name.contains(wild);
            }
        });
        if (children != null) {
            for (String child : children) {
                fileNames.add(dirName + child);
            }
        }
        return fileNames;
    }
    public static String[] getSortedDirectoryList(String dirName, String wildcard){
        List<String> dirList = getDirectoryList(dirName, wildcard);
        String[] sortedDirList = new String[dirList.size()];
        sortedDirList = dirList.toArray(sortedDirList);
        Arrays.sort(sortedDirList);
        return sortedDirList;
    }
    
    /**
     * DESCRIPTION:
     * <p>
     * convenience method to get all files in directory without wildcard
     * 
     * @param dirName name of directory to get listing of
     * @return list of filenames that exist in the directory specified
     */
    public static List<String> getDirectoryList(String dirName) {
        return getDirectoryList(dirName, "");
    }
    
    /**
     * DESCRIPTION:
     * <p>
     * deletes the specified directory and all files/subdirectories therein
     * 
     * @param dir the specified directory to delete
     * @return true if successful, false otherwise
     */
    public static boolean deleteDir(File dir) {
        boolean success = true;
        if (dir.isDirectory()) {
            String[] children = dir.list();
            for (String child : children) {
                success &= deleteDir(new File(dir, child));
            }
        }
        if (success) {
            success &= dir.delete();
        }
        return success;
    }
    
    /**
      DESCRIPTION:
      This method executes the chmod tool to set file system permissions.
      <p>
      WARNING: This method is NOT PORTABLE! It is targeted toward Unix/Linux 
      systems. It executes the chmod tool as a separate process and blocks
      until that process exits. It reads and discards any output from the 
      process in order to avoid blocking forever due to a full stream 
      condition. It is implemented in this manner because Java 1.5 has
      no provisions for setting file permissions.

      @param path the file or directory to change permissions for.
      @param mode the permissions to set (supports octal and symbolic methods)
      @return boolean to indicate success(true) or failure(false).
     */
    public static boolean chmod(String path, String mode) {
       
       // create the command line and a process builder
       String[] command = {"chmod",mode,path};
       ProcessBuilder builder = new ProcessBuilder(command);
       
       // indicate we want to merge stdout and stderr for the process
       // (otherwise we need to read/drain both streams concurrently)
       builder.redirectErrorStream(true);
       
       // initialize
       Process process = null;
       int exitStatus = -1;
       
       try {
          // start the process
          process = builder.start();
          
          // close the output stream to indicate we have no output
          // (avoids blocking forever if for some reason process reads its stdin)
          process.getOutputStream().close();
          
          // read output from the process and discard it until end of stream
          // (avoids blocking forever if the process has a lot of stdout/stderr output)
          InputStreamReader isr = new InputStreamReader(process.getInputStream());
          BufferedReader reader = new BufferedReader(isr);
          try {
             while (reader.readLine() != null);
          } finally {
             reader.close();
          }
          
          // wait for the process to terminate
          exitStatus = process.waitFor();
          
       } catch (InterruptedException e) {
          return false;
       } catch (IOException e) {
          return false;
       } finally {
          if (process != null) process.destroy();
       }
       
       // success if chmod exit status is zero
       return (exitStatus == 0);
    }
}
